#include <iostream>
#include <fstream>
#include <iomanip>
#include <list>

using namespace std;

struct TimeStruct {
	double year;
	double month;
	double day;
	double hour;
	double minute;
	double second;
};
struct DimapDataStruct {
	int nRows;
	TimeStruct refTime;
	int refLine;
	double linePeriod;
	double xyLos[8];
	double yawPitchRoll[3];
	double uv[2];
	int nXYZs;
	TimeStruct *tXYZ;
	double *XArray;
	double *YArray;
	double *ZArray;
	int nQuaternions;
	TimeStruct *tQuaternion;
	double *q0Array;
	double *q1Array;
	double *q2Array;
	double *q3Array;
};
struct ImagePointStruct {
	string id;
	bool flag;
	double x;
	double sigmax;
	double y;
	double sigmay;
};
struct GroundPointStruct {
	string id;
	char pointType;
	double X;
	double Y;
	double Z;
	double sigmaX;
	double sigmaY;
	double sigmaZ;
	struct ImagePointStruct *imagePoints;
};

// Declare functions
// Read data
string wstring2String(const wstring &inputWstring);
wstring string2Wstring(const string &inputString);
double wstring2Double(wstring inputWstring);
double* wstring2TimeInSeconds(wstring inputWstring);
double *latLongHeight2Xyz(double lat, double lon, double height);
DimapDataStruct readDimap(wstring fileName);
GroundPointStruct *readCoordinates(wstring inputFilename, list <wstring> &dimapFilenameList,
								   int &nPoints, int &mImages, int &totalImagePoints);
double *getApproximations(DimapDataStruct dimapData);
void adjustment(double *centralRow, TimeStruct *refTime, double *refLine, double *linePeriod,
				double **xyLos, int nPoints, int mImages, int totalImagePoints,
				double **imagePar0, double **Delta0, double **sigmaImagePar0,
				int nAdjustedPar, GroundPointStruct *groundPoints, ofstream &outputfp);